/**
 * GoatListCategory.java
 * 
 * FreeZzaph is free software; you can redistribute it
 * and/or modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * FreeZzaph is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.
 */

package freezzaph.plugins;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import freezzaph.exceptions.PluginException;
import freezzaph.exceptions.URLFetchException;

/**
 * Category class that takes care of what is common
 * for the Goat List Categories.
 * 
 * @author FreeZzaph
 */
public abstract class GoatListCategory extends Category {
	
	private static final Pattern link = Pattern.compile("\\d{4}-\\d{2}-\\d{2}: <a href=\"(\\S+)[^>]+>\\d+ .+ Pictures</a>\\s+-\\s+([^<]+)");
	private static final Pattern cgiKiller = Pattern.compile("/cgi-bin/.+/out.cgi.*(?:&|\\?)u=([^&]+)");
	
	private String baseURL;

	/**
	 * Construct a GoatListCategory.
	 * 
	 * @param name the name of the category
	 * @param description the description of the category
	 * @param filter the filter of the category
	 * @param baseURL the base URL of the category
	 */
	public GoatListCategory(String name, String description, String filter, String baseURL) {
		super(name, description, filter);
		this.baseURL = baseURL;
	}

	/*
	 * (non-Javadoc)
	 * @see freezzaph.plugins.Category#fetch(int, int)
	 */
	@Override final public URL[] fetch(int startPage,int count) {
		int currentCount = 0;
		int page = startPage + 1;
		int realCount = count;
		if (realCount == -1) realCount = 100;
		
		ArrayList<URL> urls = new ArrayList<URL>();
		HashMap<String, Object> duplicatePreventor = new HashMap<String, Object>(realCount);
		while (currentCount < realCount) {
			
			// Generate URL for this session
			URL categoryURL = null;
			try {
				categoryURL = new URL(baseURL + page + ".shtml");
			} catch (MalformedURLException e) {
				// Won't happen
			}
			
			// Fetch (X)HTML data for parsing
			String sb;
			try {
				sb = URLFetcher.fetch(categoryURL);
			} catch (URLFetchException e) {
				throw new PluginException("Could not download category list. GoatList.com may not be accessible, or the plugin may need to be updated.", e);
			}
			
			Matcher m = link.matcher(sb);
			while (m.find() && currentCount < realCount) {
				
				// If this is a special CGI catching URL,
				// extract the *real* URL from it.
				Matcher n = cgiKiller.matcher(m.group(1));
				String path;
				if (n.find()) {
					path = n.group(1);
				} else {
					path = m.group(1);						
				}
				
				if (!duplicatePreventor.containsKey(path) && path.startsWith("http")) {
					// Ignore duplicates
					try {
						URL url = new URL(path);
						urls.add(url);
						currentCount++;
						duplicatePreventor.put(path, null);
					} catch (MalformedURLException e) {
						// When a URL is malformed
						// Just ignore it.
					}
				}
			}
			page++;
		}
		return urls.toArray(new URL[0]);
		
	}

}
